/** 
 * 文件名：NginxLogUtil.java 
 * 
 * 版本信息： 
 * 日期：2015年8月29日 
 * Copyright 足下 Corporation 2015 
 * 版权所有 
 * 
 */

package com.qyer.util.log.util;

import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang.StringUtils;

import com.qyer.util.log.common.Constants;
import com.qyer.util.log.entity.AppTrackLog;
import com.qyer.util.log.entity.ArsalNginxLog;
import com.qyer.util.log.entity.NginxLog;

/**
 * 此类描述的是： 原始日志工具类
 * 
 * @author: hongxi.sun@qyer.com
 * @version:  2015年8月29日 下午3:23:38
 */
public class AppLogUtil {
	/**
	 * 判断参数是否为null或者-,是则返回空字符串,否则不做任何处理返回原参数
	 * @param str 需要判断的参数
	 * @author: hongxi.sun@qyer.com
	 * @version:  2015年8月29日 下午3:23:38
	 * @return 
	 */
	public static String formatField(String str){
		if( str==null ||"".equals(str.trim())|| "-" .equals(str)){
			return "";
		}			
		return str;
	}

	/**
	 * 此方法描述的是：解析nginx日志格式成NginxLog对象
	 * @param strLine  一行原始Nginx日志
	 * @author: hongxi.sun@qyer.com
	 * @version: 2015年8月29日 下午3:23:38
	 * @return 返回NginxLog对象,出现异常返回null
	 */
	public static NginxLog getNginxLog(String strLine) {
		if (strLine == null || strLine.equals("")) {
			return null;
		}
		
		String   remote_addr="";   
		String   remote_user="";  
		String   time_local	="";  
		String   request="";  
		String   status=""; 
		String   body_bytes_sent="";
		String   http_referer="";
		String   http_user_agent="";
		String   http_x_forwarded_fo="";
		String   request_body="";
		
		String [] ls = StringUtils.split(strLine , Constants.FS);
		if(ls.length<10){
			return null ; 
		}
		
		remote_addr=ls[0];
		remote_user=ls[1];
		time_local=ls[2];
		request=ls[3];
		status=ls[4];
		body_bytes_sent=ls[5];
		http_referer=ls[6];
		http_user_agent=ls[7];
		http_x_forwarded_fo=ls[8];
		request_body=ls[9];
		
		NginxLog nginxLog = new NginxLog();
		nginxLog.setRemote_addr(formatField(remote_addr));
		nginxLog.setRemote_user(formatField(remote_user));
		nginxLog.setTime_local(formatField(time_local));
		nginxLog.setRequest(formatField(request));
		nginxLog.setStatus(formatField(status));
		nginxLog.setBody_bytes_sent(formatField(body_bytes_sent));
		nginxLog.setHttp_referer(formatField(http_referer));
		nginxLog.setHttp_user_agent(formatField(http_user_agent));
		nginxLog.setHttp_x_forwarded_fo(http_x_forwarded_fo);
		nginxLog.setRequest_body(request_body);
		return nginxLog;
	}
	
	
	/**
	 * 此方法描述的是：解析nginx日志格式成NginxLog对象
	 * @param strLine  一行原始Nginx日志
	 * @author: hongxi.sun@qyer.com
	 * @version: 2015年8月29日 下午3:23:38
	 * @return 返回NginxLog对象,出现异常返回null
	 */
	public static ArsalNginxLog getArsalNginxLog(String strLine) {
		if (strLine == null || strLine.equals("")) {
			return null;
		}
		
		String   remote_addr="";   
		String   remote_user="";  
		String   time_local	="";  
		String   request="";  
		String   status=""; 
		String   body_bytes_sent="";
		String   http_referer="";
		String   http_user_agent="";
		String   http_x_forwarded_fo="";
		String   request_body="";
		
		String [] ls = StringUtils.split(strLine , Constants.FS);
		if(ls.length<10){
			return null ; 
		}
		
		remote_addr=ls[0];
		remote_user=ls[1];
		time_local=ls[2];
		request=ls[3];
		status=ls[4];
		body_bytes_sent=ls[5];
		http_referer=ls[6];
		http_user_agent=ls[7];
		http_x_forwarded_fo=ls[8];
		request_body=ls[9];
		
		ArsalNginxLog nginxLog = new ArsalNginxLog();
		nginxLog.setRemote_addr(formatField(remote_addr));
		nginxLog.setRemote_user(formatField(remote_user));
		nginxLog.setTime_local(formatField(time_local));
//		nginxLog.setRequest(formatField(request));
		nginxLog.setStatus(formatField(status));
		nginxLog.setBody_bytes_sent(formatField(body_bytes_sent));
		nginxLog.setHttp_referer(formatField(http_referer));
		nginxLog.setHttp_user_agent(formatField(http_user_agent));
//		nginxLog.setHttp_x_forwarded_fo(http_x_forwarded_fo);
		nginxLog.setRequest_body(request_body);
		return nginxLog;
	}

	/**
	 * 此方法描述的是：解析url
	 * @param strLine  一行原始Nginx日志
	 * @author: hongxi.sun@qyer.com
	 * @version: 2015年8月29日 下午3:23:38
	 * @return Map<String , String > 
	 */
	public static Map<String, String> analysisTrackUrl(String trackURL) {
		Map<String, String> mapTrackUrl = new HashMap<String, String>();
		if (trackURL == null || trackURL.equals("")) {
			return mapTrackUrl;
		}
		String strTrackURL = trackURL;
		strTrackURL = strTrackURL.replace("，", ",").replace("{", "")
				.replace("｛", "").replace("}", "").replace("｝", "")
				.replace(" ", "").replace("：", ":").replace(":", "==")
				.replace("‘", "'").replace("','", "|").replace(",'", "|")
				.replace("',", "|");
		String[] paramList = strTrackURL.split("\\|");
		for (String param : paramList) {
			param = param.replace("'", "").trim();
			if (param.contains("==")) {
				String[] arrTmp = param.split("==");
				if (arrTmp.length == 2) {
					mapTrackUrl.put(param.split("==")[0], param.split("==")[1]);
				}
			}
		}
		return mapTrackUrl;
	}

	/**
	 * 此方法描述的是：解析url
	 * @param strLine  一行原始Nginx日志
	 * @author: hongxi.sun@qyer.com
	 * @version: 2015年8月29日 下午3:23:38
	 * @return Map<String , String > 
	 */
	public static Map<String, String> requestParamUrlToMap(String requestParamStr) {
		Map<String, String> requestParamMap = new HashMap<String, String>();

		for (String kv : requestParamStr.split("&")) {
			kv = preProcess(kv, "utf-8");

			if (kv != null && kv.indexOf("=") != -1) {
				int indexTmp = kv.indexOf("=");
				if (indexTmp != kv.length() - 1) {
					requestParamMap.put(kv.substring(0, indexTmp),kv.substring(indexTmp + 1, kv.length()));
				} else {
					requestParamMap.put(kv.substring(0, indexTmp), "");
				}

			}
		}

		return requestParamMap;
	}

	public static String getOtherParm(Map<String, String> requestParamMap){
		StringBuffer bf = new StringBuffer();
		for (Map.Entry<String, String> entry : requestParamMap.entrySet()) { 
			String key = entry.getKey();
			String val = entry.getValue();
			if(!key.equals("trackURL")){
				bf.append(key);
				bf.append("=");
				bf.append(val);
				bf.append("&");
			}
		}
		return bf.toString().substring(0, bf.toString().length()-1);
	}
	
	/**
	 * 此方法描述的是：URL  decode
	 * @param strLine  一行原始Nginx日志
	 * @author: hongxi.sun@qyer.com
	 * @version: 2015年8月29日 下午3:23:38
	 * @return String
	 */
	private static String preProcess(String strSources, String strCode) {
		if (!strCode.isEmpty()) {
			try {
				strSources = URLDecoder.decode(strSources, strCode);
				strSources=strSources.replace("\001", "");
				strSources=strSources.replace("\002", "");
				strSources=strSources.replace("\003", "");
				strSources=strSources.replace("\004", "");
				strSources=strSources.replace("\005", "");
				strSources=strSources.replace("\006", "");
				strSources=strSources.replace("\n", "");
				strSources=strSources.replace("\r", "");
			} catch (Exception e) {
				return "";
			}
		}
		return strSources;
	}

	/**
	 * 此方法描述的是：初始化 日志父类
	 * @param strLine  一行原始Nginx日志
	 * @author: hongxi.sun@qyer.com
	 * @version: 2015年8月29日 下午3:23:38
	 * @return 是否成功
	 */
	public static Boolean initBaseLog(NginxLog nginxLog, AppTrackLog trackLog) {
		
		if (nginxLog == null) {
			return false;
		}

		if (nginxLog.getRequest().indexOf("GET ") > -1 && nginxLog.getRequest().indexOf("HTTP/") >-1) {
			String requestParam = nginxLog.getRequest().substring(nginxLog.getRequest().indexOf("GET ") + 4,nginxLog.getRequest().indexOf(" HTTP/"));
			
			requestParam=requestParam.replaceAll("&amp;", "&");
			
			trackLog.getParamsMap().putAll(AppLogUtil.requestParamUrlToMap(requestParam));
			trackLog.setType("/open");
		}else if (nginxLog.getRequest().indexOf("POST ") > -1&& nginxLog.getRequest().indexOf("HTTP/") > -1){
			String requestParam = nginxLog.getRequest().substring(nginxLog.getRequest().indexOf("POST ") + 5,nginxLog.getRequest().indexOf(" HTTP/"));
			trackLog.setType(requestParam);

			String requestbody= nginxLog.getRequest_body();
			if(requestbody.contains("\\x0A")||requestbody.contains("\\x0D")){
				requestbody=StringUtils.replace(requestbody , "\\x0A", "=");
				requestbody=StringUtils.replace(requestbody , "\\x0D", "");
				requestbody=StringUtils.replace(requestbody ,"\\x22", "");
				requestbody=StringUtils.replace(requestbody ,"; name=", "");
				requestbody=StringUtils.replace(requestbody ,"------------------------------", "");
				requestbody=StringUtils.replace(requestbody ,"==", "=");
				
				String [] s =requestbody.split("Content-Disposition: form-data");
				
				for(String ss :s ){
					String[] kv = ss.split("=");
			 		if(kv.length>1){
			 			trackLog.getParamsMap().put(kv[0], kv[1]);
			 		}
			 	}
			}else{
				trackLog.getParamsMap().putAll(AppLogUtil.requestParamUrlToMap(requestbody));
			}
		}else{
			return false;
		}
		
		trackLog.setApiPath((preProcess(nginxLog.getRequest(), "utf-8")));
		trackLog.setUserIp(nginxLog.getRemote_addr());
		trackLog.setUserAgent(nginxLog.getHttp_user_agent());
		trackLog.setPlatform("app");
		trackLog.setUserId(trackLog.getParamsMap().get("track_user_id"));
		trackLog.setLon(trackLog.getParamsMap().get("lon"));
		trackLog.setLat(trackLog.getParamsMap().get("lat"));
		trackLog.setAppVersion(trackLog.getParamsMap().get("track_app_version"));
		trackLog.setInstalltime(trackLog.getParamsMap().get("installtime"));
		trackLog.setInfo(trackLog.getParamsMap().get("info"));
		trackLog.setDeviceInfo(trackLog.getParamsMap().get("track_device_info"));
		trackLog.setUserIp(trackLog.getParamsMap().get("ip"));
		trackLog.setClientSecret(trackLog.getParamsMap().get("client_secret"));
		trackLog.setAppChannel(trackLog.getParamsMap().get("track_app_channel"));
		trackLog.setOs(trackLog.getParamsMap().get("track_os"));
		trackLog.setClientId(trackLog.getParamsMap().get("client_id"));
		trackLog.setDeviceid(trackLog.getParamsMap().get("track_deviceid"));
		trackLog.setApiName(trackLog.getParamsMap().get("api_name"));
		trackLog.setAuthToken(trackLog.getParamsMap().get("oauth_token"));
		trackLog.setDeviceName(trackLog.getParamsMap().get("device_name"));
		
		if(trackLog.getParamsMap().containsKey("timestamp")){
			Long ts = Long.parseLong(trackLog.getParamsMap().get("timestamp"));
			ts=ts*1000; 
			trackLog.setTimeStamp(ts.toString());
		}
		
		return true;
	}
}
